<template>
  <transition name="modal-fade">
    <div
      v-if="isVisible"
      class="draggable-modal"
      ref="modalRef"
      :style="{
        left: `${left}px`,
        top: `${top}px`,
        position: 'fixed',
        zIndex: 2000,
      }"
    >
      <div class="modal-header" @mousedown="handleMouseDown">
        <div class="header-title">{{ props.title }}</div>
        <button class="close-button" @click="closeModal">×</button>
      </div>
      <div class="modal-content">
        <slot>默认内容</slot>
      </div>
    </div>
  </transition>
</template>

<script setup>
import {
  ref,
  defineProps,
  defineEmits,
  watch,
  onMounted,
  onUnmounted,
  shallowRef,
  watchEffect,
} from 'vue';

// 接收父组件传递的可见性状态
const props = defineProps({
  modelValue: {
    type: Boolean,
    default: true,
  },
  title: {
    type: String,
    default: 'nihao',
  },

  width: {
    type: String,
    default: '',
  },
});

const modalRef = shallowRef(null);

const modalWidth = ref('300px');

const emit = defineEmits(['update:modelValue']);

// 弹窗是否可见
const isVisible = ref(props.modelValue);

// 监听 props.modelValue 的变化
watch(
  () => props.modelValue,
  (newValue) => {
    isVisible.value = newValue;
  }
);

// 弹窗位置
const left = ref(100);
const top = ref(100);

// 拖动状态
const isDragging = ref(false);
// 记录鼠标按下时的位置
let startMouseX = 0;
let startMouseY = 0;
// 记录模态框初始位置
let initialLeft = 0;
let initialTop = 0;

const handleMouseDown = (event) => {
  isDragging.value = true;
  startMouseX = event.clientX;
  startMouseY = event.clientY;
  initialLeft = left.value;
  initialTop = top.value;
  document.addEventListener('mousemove', handleDocumentMouseMove);
  document.addEventListener('mouseup', handleDocumentMouseUp);
};

const handleDocumentMouseMove = (event) => {
  if (!isDragging.value) return;

  const deltaX = event.clientX - startMouseX;
  const deltaY = event.clientY - startMouseY;

  left.value = initialLeft + deltaX;
  top.value = initialTop + deltaY;
};

const handleDocumentMouseUp = () => {
  isDragging.value = false;
  document.removeEventListener('mousemove', handleDocumentMouseMove);
  document.removeEventListener('mouseup', handleDocumentMouseUp);
};

// 关闭弹窗
const closeModal = () => {
  isVisible.value = false;
  emit('update:modelValue', false);
};

const toCenter = () => {
  if (!modalRef.value) return;
  const { width, height } = modalRef.value.getBoundingClientRect();
  left.value = (window.innerWidth - width) / 2;
  top.value = (window.innerHeight - height - 200) / 2;
};

onMounted(() => {
  toCenter();
});

onUnmounted(() => {
  document.removeEventListener('mouseup', handleDocumentMouseUp);
  document.removeEventListener('mousemove', handleDocumentMouseMove);
});
</script>

<style scoped>
.draggable-modal {
  position: fixed;
  background-color: white;
  border: 1px solid #ccc;
  border-radius: 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  width: v-bind(modalWidth);
  min-height: 100px;
}

.modal-header {
  padding: 10px;
  background-color: #f0f0f0;
  cursor: move;
  display: flex;
  justify-content: space-between;
  align-items: center;
  user-select: none;
}

.modal-content {
  padding: 10px;
}

.close-button {
  background: none;
  border: none;
  font-size: 20px;
  cursor: pointer;
}

/* 弹窗动画 */
.modal-fade-enter-active,
.modal-fade-leave-active {
  transition: opacity 0.3s ease;
}
.modal-fade-enter-from,
.modal-fade-leave-to {
  opacity: 0;
}
</style>
